<template>
    <!-- 整体布局 -->
    <div class="order-deliver-container">
        <!-- 左边交付布局 -->
        <div class="order-deliver-left">
            <!-- 交付抬头 -->
            <div class="order-deliver-header">
                <!-- 第一行：标题 -->
                <div class="w-full text-2xl text-center">订单交付</div>
                <!-- 第二行：客户名称 -->
                <div class="w-full flex items-center">
                    <div style="width: 100px">客户名称：</div>
                    <el-autocomplete
                        v-model="deliverForm.customerInfo.customerName"
                        :fetch-suggestions="queryCustomerSearch"
                        clearable
                        @select="handleCustomerSelect"
                        @clear="handleCustomerClear"
                    />
                </div>
                <!-- 第三行：送货信息 -->
                <div class="w-full flex items-center justify-between">
                    <div class="flex items-center mr-1">
                        <div style="width: 125px">送货地址：</div>
                        <el-input v-model="deliverForm.customerInfo.customerAddress" clearable />
                    </div>
                    <div class="flex items-center">
                        <div style="width: 125px">联系电话：</div>
                        <el-input v-model="deliverForm.customerInfo.customerPhone" clearable />
                    </div>
                </div>
                <!-- 第四行：按钮交互 -->
                <div class="w-full flex items-center justify-between">
                    <div class="flex items-center">
                        <el-button class="mr-2" type="primary" plain :icon="Refresh" @click="refreshDeliveredListEvent">刷新 </el-button>
                        <!-- 导入按钮 -->
                        <el-dropdown :disabled="deliverForm.customerInfo.customerName == ''" trigger="click">
                            <el-button
                                class="mr-2"
                                type="primary"
                                plain
                                :icon="ArrowSortDownLines20Filled"
                                :disabled="deliverForm.customerInfo.customerName == ''"
                            >
                                导入
                            </el-button>
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <el-dropdown-item :icon="TableBuilt" @click="onlineOrderOpenEvent">在线导入</el-dropdown-item>
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                        <!-- 提交按钮 -->
                        <el-button type="primary" :icon="Check" plain @click="submitDeliverFormEvent" :disabled="deliverForm.deliverList.length == 0">
                            提交
                        </el-button>
                    </div>
                </div>
            </div>
            <!-- 交付内容 -->
            <div class="order-deliver-content">
                <VTable
                    v-if="records.length"
                    v-model:table-instance="tableInstance"
                    height="calc(100vh - 300px)"
                    v-model:records="records"
                    v-model:columns="columns"
                    v-model:width-mode="widthMode"
                    @change_cell_value="changeCellValueEvent"
                ></VTable>
            </div>
        </div>
        <!-- 右边订单信息布局 -- 选择客户 -->
        <div v-if="deliverForm.customerInfo.customerName" class="order-deliver-right">
            <div class="order-info-title">未发货订单列表</div>
            <div class="order-info-search">
                <el-input v-model="searchUnDeliveredKeyword" placeholder="请搜索关键字 按ENTER搜索" clearable @change="searchUnDeliveredListEvent" />
            </div>
            <!-- 循环所选客户所有未发货订单信息 -->
            <el-scrollbar height="calc(100vh - 180px)">
                <div class="order-info-container" v-for="item in unDeliveredList" :key="item._id">
                    <div class="order-info-checked">
                        <el-checkbox v-model="item.checked" :indeterminate="false" @change="addDeliveredListEvent(item)"></el-checkbox>
                    </div>
                    <div class="order-info-item">
                        <div class="w-full">订单号：{{ item.orderNo }}</div>
                        <div class="w-full">订单日期：{{ formatTimeZone(item.orderDate, 'YYYY-MM-DD') }}</div>
                        <div class="w-full">产品名称：{{ item.productName }}</div>
                        <div class="w-full">订单数量：{{ item.orderNumber }}</div>
                        <div class="w-full">送货数量：{{ item.deliveryQuantity }}</div>
                    </div>
                </div>
            </el-scrollbar>
        </div>
        <!-- 右边订单信息布局 -- 未选择客户 -->
        <div v-if="!deliverForm.customerInfo.customerName" class="order-deliver-right">
            <div class="order-info">
                <div class="mt-2 w-full text-center text-xl">请先选择客户后加载订单信息...</div>
            </div>
        </div>
    </div>

    <OnlineTable
        v-model:online-table-visible="onlineTableVisible"
        :un-delivered-list="unDeliveredList"
        :all-delivered-list="allDeliveredList"
        :customer-id="deliverForm.customerInfo._id"
    ></OnlineTable>
</template>

<script setup lang="ts">
import { formatTimeZone } from '@utils/calculate';
import { ListTable } from '@visactor/vtable';
import { ArrowSortDownLines20Filled } from '@vicons/fluent';
import { Refresh } from '@vicons/tabler';
import { TableBuilt } from '@vicons/carbon';
import { Check } from '@element-plus/icons-vue';
import { getCustomerList } from '@/api/customer';
import { getAllUnDeliveryOrderListByCustomerId } from '@/api/order';
import { createOutBound } from '@/api/outbound';
import { getProductStock } from '@/api/product';
import { useSystemStore } from '@/store/modules/system';

onMounted(() => {
    // 获取客户列表
    getAllCustomerListEvent();
});

/* ***********************************通用属性/方法*********************************** */
// 客户类型
type Customer = {
    _id: string;
    customerName: string;
    customerAddress: string;
    customerPhone: string;
};
// 准备提交的交付列表类型
type DeliveredList = {
    _id: string;
    orderNo: string;
    orderDetail: {
        productId: string;
        materialNumber: string;
        productName: string;
        productSize: string;
        orderNumber: number;
        deliveryQuantity: number;
        excludTaxPrice: number;
        includeTaxPrice: number;
        subtotal: number;
        remark: string;
    };
}[];
// 准备提交的交付表单
const deliverForm = reactive<{ customerInfo: Customer; deliverList: DeliveredList }>({
    customerInfo: { _id: '', customerName: '', customerAddress: '', customerPhone: '' },
    deliverList: [],
});
// 所有订单列表
const allDeliveredList = reactive<AjaxResponse['orderList']>([]);

// 加工后 未交付列表类型
type UnDeliveredList = {
    checked: boolean;
    _id: string;
    orderDate: string;
    orderNo: string;
    productId: string;
    materialNumber: string;
    productName: string;
    orderNumber: number;
    deliveryQuantity: number;
}[];
// 未交付列表
const unDeliveredList = reactive<UnDeliveredList>([]);
// 缓存未交付列表
const cache = reactive<UnDeliveredList>([]);

// 使用客户id获取所有对应未发货订单列表
const getAllUnDeliveryOrderListByCustomerIdEvent = (customerId: string) => {
    if (customerId == '') {
        ElMessage.warning('请先选择客户...');
        return;
    }

    // 清空数据
    allDeliveredList.length = 0;
    unDeliveredList.length = 0;
    cache.length = 0;

    getAllUnDeliveryOrderListByCustomerId(customerId).then((res) => {
        ElMessage.success(res.message);
        // 循环数据
        res.data.forEach((item: AjaxResponse['orderList'][0]) => {
            allDeliveredList.push(item);
            // 循环订单详情
            item.orderDetail.forEach((detailItem: AjaxResponse['orderList'][0]['orderDetail'][0]) => {
                // 当送货数量小于订单数量时才添加
                if (detailItem.deliveryQuantity < detailItem.orderNumber) {
                    let obj = {
                        checked: false,
                        _id: item._id,
                        orderDate: item.orderDate,
                        orderNo: item.orderNo,
                        productId: detailItem.productId,
                        materialNumber: detailItem.materialNumber,
                        productName: detailItem.productName,
                        orderNumber: detailItem.orderNumber,
                        deliveryQuantity: detailItem.deliveryQuantity,
                    };
                    unDeliveredList.push(obj);
                    cache.push(obj);
                }
            });
        });
    });
};

/* ***********************************客户自动补全框属性/方法*********************************** */
// 所有客户列表
const customerList = reactive<AjaxResponse['customerList']>([]);
// 获取全部客户列表
const getAllCustomerListEvent = () => {
    // 清空数据
    customerList.length = 0;
    // 获取所有客户列表
    getCustomerList(true).then((res) => {
        res.data.forEach((item) => {
            item.value = item.customerName;
            customerList.push(item);
        });
    });
};
// 自动填充框
const queryCustomerSearch = (queryString: string, cb: any) => {
    const results = queryString ? customerList.filter(createCustomerFilter(queryString)) : customerList;
    // call callback function to return suggestions
    cb(results);
};
// 过滤器
const createCustomerFilter = (queryString: string) => {
    return (customer: AjaxResponse['customerList'][0]) => {
        // 正则处理特殊符号
        const regex = /[.*+?^${}()|[\]\\]/;
        const match = queryString.replace(regex, '\\$&');
        const reg = new RegExp(match, 'i');
        if (reg.test(customer.customerName)) {
            return true;
        }
    };
};
// 监听选择客户
const handleCustomerSelect = (item: Record<string, any>) => {
    deliverForm.customerInfo._id = item._id;
    deliverForm.customerInfo.customerName = item.customerName;
    deliverForm.customerInfo.customerAddress = item.customerAddress;
    deliverForm.customerInfo.customerPhone = item.customerPhone;
    getAllUnDeliveryOrderListByCustomerIdEvent(item._id);
};
// 监听清空客户
const handleCustomerClear = () => {
    deliverForm.customerInfo._id = '';
    deliverForm.customerInfo.customerName = '';
    deliverForm.customerInfo.customerAddress = '';
    deliverForm.customerInfo.customerPhone = '';
    deliverForm.deliverList.length = 0;
};

/* ***********************************刷新交付列表属性/方法*********************************** */
const refreshDeliveredListEvent = () => {
    // 清空数据
    allDeliveredList.length = 0;
    unDeliveredList.length = 0;
    deliverForm.deliverList.length = 0;
    records.length = 0;
    tableInstance.value?.setRecords(records);
    // 获取所有未发货订单
    getAllUnDeliveryOrderListByCustomerIdEvent(deliverForm.customerInfo._id);
};

/* ***********************************添加交付列表属性/方法*********************************** */
const addDeliveredListEvent = (item: UnDeliveredList[0]) => {
    // 勾选未发订单
    if (item.checked) {
        // 查询订单内容
        const order = allDeliveredList.find((i) => i._id == item._id);
        // 添加对应订单详情
        for (let index = 0; index < order!.orderDetail.length; index++) {
            const o = order!.orderDetail[index];
            if (o.productName == item.productName) {
                deliverForm.deliverList.push({
                    _id: item._id,
                    orderNo: item.orderNo,
                    orderDetail: {
                        productId: o.productId,
                        materialNumber: o.materialNumber,
                        productName: o.productName,
                        productSize: o.productSize,
                        orderNumber: o.orderNumber,
                        deliveryQuantity: o.deliveryQuantity,
                        excludTaxPrice: o.excludTaxPrice,
                        includeTaxPrice: o.includeTaxPrice,
                        subtotal: o.subtotal,
                        remark: o.remark,
                    },
                });
                return;
            }
        }
    } else {
        // 反勾选未发订单
        const index = deliverForm.deliverList.findIndex((i) => {
            return i._id == item._id && i.orderDetail.productName == item.productName;
        });
        deliverForm.deliverList.splice(index, 1);
    }
};

/* ***********************************搜索未发订单属性/方法*********************************** */
// 搜索未发订单关键字
const searchUnDeliveredKeyword = ref('');
// 搜索未发订单的方法
const searchUnDeliveredListEvent = () => {
    // 搜索值为空
    if (searchUnDeliveredKeyword.value == '') {
        // 重置数据
        unDeliveredList.length = 0;
        // 从缓存中添加数据
        cache.forEach((item) => {
            unDeliveredList.push(item);
        });
    } else {
        // 重置数据
        unDeliveredList.length = 0;
        cache.forEach((item) => {
            if (item.productName.includes(searchUnDeliveredKeyword.value) || item.orderNo.includes(searchUnDeliveredKeyword.value)) {
                unDeliveredList.push(item);
            }
        });
    }
};

/* ***********************************Vtable属性/方法*********************************** */
// 表格实例
const tableInstance = ref<ListTable>();
// 含税标识
const taxIncluded = ref(false);

// 表单内容类型
type Records = {
    orderId: string;
    orderNo: string;
    materialNumber: string;
    productId: string;
    productName: string;
    productSize: string;
    orderNumber: number;
    deliveryQuantity: number;
    unit: '只';
    price: number;
    subtotal: number;
    remark: string;
};
// 表单内容
const records = reactive<Records[]>([]);
// 监听交付列表的变化，实时计算表单内容
watch(
    () => deliverForm.deliverList,
    () => {
        // 做一次缓存
        const tmp = [...records];
        // 清空数据
        records.length = 0;
        // 注意含税标识的变化，一个公司内不能同时包含 含税 和 不含税
        for (let index = 0; index < deliverForm.deliverList.length; index++) {
            const deliverList = deliverForm.deliverList[index];

            // 获取当前是否含税标识
            const flag = taxIncluded.value;

            // 计算订单不含税的情况
            if (
                Number((deliverList.orderDetail.subtotal / deliverList.orderDetail.orderNumber).toFixed(2)) == deliverList.orderDetail.excludTaxPrice
            ) {
                // 设置当前是否含税标识
                taxIncluded.value = false;

                // 第二次循环检查含税标识是否对比第一次发生变化
                if (index !== 0) {
                    if (flag !== taxIncluded.value) {
                        deliverForm.deliverList.length = 0;
                        ElMessage.warning('当前出库单内不能同时包含含税和不含税');
                    }
                }
                // 返回不含税数据
                records.push({
                    orderId: deliverList._id,
                    orderNo: deliverList.orderNo,
                    materialNumber: deliverList.orderDetail.materialNumber,
                    productId: deliverList.orderDetail.productId,
                    productName: deliverList.orderDetail.productName,
                    productSize: deliverList.orderDetail.productSize,
                    orderNumber: deliverList.orderDetail.orderNumber,
                    deliveryQuantity: returnRecords(tmp, deliverList),
                    unit: '只',
                    price: deliverList.orderDetail.excludTaxPrice,
                    // 按照出库数量算价格
                    subtotal: Number((deliverList.orderDetail.excludTaxPrice * returnRecords(tmp, deliverList)).toFixed(2)),
                    remark: deliverList.orderDetail.remark || '',
                });
            } else {
                // 设置当前是否含税标识
                taxIncluded.value = false;

                // 第二次循环检查含税标识是否对比第一次发生变化
                if (index !== 0) {
                    if (flag !== taxIncluded.value) {
                        deliverForm.deliverList.length = 0;
                        ElMessage.warning('当前出库单内不能同时包含含税和不含税');
                    }
                }
                // 含税的情况
                records.push({
                    orderId: deliverList._id,
                    orderNo: deliverList.orderNo,
                    materialNumber: deliverList.orderDetail.materialNumber,
                    productId: deliverList.orderDetail.productId,
                    productName: deliverList.orderDetail.productName,
                    productSize: deliverList.orderDetail.productSize,
                    orderNumber: deliverList.orderDetail.orderNumber,
                    deliveryQuantity: returnRecords(tmp, deliverList),
                    unit: '只',
                    price: deliverList.orderDetail.includeTaxPrice,
                    // 按照出库数量算价格
                    subtotal: Number((deliverList.orderDetail.includeTaxPrice * returnRecords(tmp, deliverList)).toFixed(2)),
                    remark: deliverList.orderDetail.remark || '',
                });
            }
        }

        tableInstance.value?.setRecords(records);
    },
    { deep: true }
);
// 监听交付列表的变化时，如果之前有改动则复原
const returnRecords = (records: Records[], deliverList: DeliveredList[number]): number => {
    // 查找之前的记录
    const preRecord = records.find((item) => item.orderId == deliverList._id && item.productId == deliverList.orderDetail.productId);
    if (preRecord) {
        return preRecord.deliveryQuantity;
    }
    return deliverList.orderDetail.orderNumber - deliverList.orderDetail.deliveryQuantity;
};

// 表头
let columns = [
    {
        field: 'orderNo',
        title: '订单号',
        width: 'auto',
    },
    {
        field: 'materialNumber',
        title: '物料号',
        width: 'auto',
    },
    {
        field: 'productName',
        title: '产品名称',
        width: 'auto',
    },
    {
        field: 'productSize',
        title: '产品尺寸',
        width: 'auto',
    },
    {
        field: 'orderNumber',
        title: '订单数量',
        width: 'auto',
    },
    {
        field: 'deliveryQuantity',
        title: '送货数量',
        width: 'auto',
        editor: 'deliveryQuantity-editor',
    },
    {
        field: 'unit',
        title: '单位',
        width: 'auto',
        editor: 'unit-editor',
    },
    {
        field: 'price',
        title: '单价',
        width: 'auto',
    },
    {
        field: 'subtotal',
        title: '总计',
        width: 'auto',
    },
    {
        field: 'remark',
        title: '备注',
        width: 'auto',
        editor: 'remark-editor',
    },
];
// 宽度模式
const widthMode = ref<'adaptive' | 'standard' | 'autoWidth'>('adaptive');
// 编辑送货数量验证
const changeCellValueEvent = async (
    orderId: string,
    productId: string,
    changedValue: number | string,
    rawValue: number | string,
    editIndex: number
) => {
    // 检查订单要出库的产品是否有库存
    const productResult = await getProductStock(deliverForm.customerInfo._id, productId);
    if (productResult.data < Number(changedValue)) {
        ElMessage.error(`库存不足，当前产品库存：${productResult.data}只，请重新输入！`);
        records.forEach((item, index) => {
            if (item.orderId == orderId && item.productId == productId && index == editIndex) {
                item.deliveryQuantity = Number(rawValue);
                // 重新计算价格
                item.subtotal = Number((item.price * item.deliveryQuantity).toFixed(2));
            }
        });
        tableInstance.value?.setRecords(records);
        return;
    } else {
        // 计算价格
        records.forEach((item, index) => {
            if (item.orderId == orderId && item.productId == productId && index == editIndex) {
                item.deliveryQuantity = Number(changedValue);
                // 重新计算价格
                item.subtotal = Number((item.price * item.deliveryQuantity).toFixed(2));
            }
        });
        tableInstance.value?.setRecords(records);
        return;
    }
};

/* ***********************************导入提交属性/方法*********************************** */
// 在线表单弹窗
const onlineTableVisible = ref(false);
watch(
    () => onlineTableVisible.value,
    (newValue) => {
        // 弹窗关闭的时候，重新加载一次未发订单数据
        if (!newValue) {
            getAllUnDeliveryOrderListByCustomerIdEvent(deliverForm.customerInfo._id);
        }
    }
);
// 弹出在线订单弹窗
const onlineOrderOpenEvent = () => {
    if (deliverForm.customerInfo.customerName == '') {
        ElMessage.warning('请先选择客户！');
        return;
    }
    onlineTableVisible.value = true;
};
// 提交订单交付
const submitDeliverFormEvent = () => {
    // 验证数据是否完整
    const index = records.findIndex((item) => item.deliveryQuantity === 0);
    if (index != -1) {
        ElMessage.error(`第${index + 1}行的送货数量为0，请检查后重新提交！`);
        return;
    }

    createOutBound('system', deliverForm.customerInfo._id, records).then((res) => {
        ElMessage.success(res.message);
        allDeliveredList.length = 0;
        unDeliveredList.length = 0;
        deliverForm.deliverList.length = 0;
        records.length = 0;
        tableInstance.value?.setRecords(records);
        getAllUnDeliveryOrderListByCustomerIdEvent(deliverForm.customerInfo._id);
    });
};

// 系统配置
const useSystem = useSystemStore();
// 计算宽度
const orderDeliverContainerWidth = computed(() => {
    return useSystem.config.isCollapse ? 'calc(100vw - 84px)' : 'calc(100vw - 220px)';
});
// 计算左边宽度
const orderDeliverLeftWidth = computed(() => {
    return useSystem.config.isCollapse ? 'calc(100vw - 394px)' : 'calc(100vw - 530px)';
});
</script>

<style scoped lang="scss">
.order-deliver-container {
    width: v-bind(orderDeliverContainerWidth);
    height: calc(100vh - 80px);
    display: flex;
    justify-content: space-between;

    // 订单交付左边
    .order-deliver-left {
        width: v-bind(orderDeliverLeftWidth);
        height: calc(100vh - 80px);
        display: flex;
        flex-wrap: wrap;
        align-content: space-between;
        .order-deliver-header {
            width: 100%;
            height: 180px;
            background-color: #9fc1dd;
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            justify-content: space-between;
            padding: 5px;
            border-radius: 0.25rem;
            color: white;
            gap: 10px;
        }
        .order-deliver-content {
            width: 100%;
            height: calc(100vh - 265px);
            padding: 10px;
            background-color: #9fc1dd;
            border-radius: 0.25rem;
            color: rgb(0, 0, 0);
        }
    }
    // 订单交付右边
    .order-deliver-right {
        width: 300px;
        height: calc(100vh - 80px);
        background-color: #9fc1dd;
        overflow: hidden;
        color: white;
        .order-info-title {
            font-size: 1.1rem;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .order-info-search {
            padding: 10px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .order-info-container {
            display: flex;
            margin: 10px;
            border-radius: 4px;
            background: var(--el-color-primary-light-9);
            color: var(--el-color-primary);
            .order-info-checked {
                display: flex;
                align-items: center;
                justify-content: center;
                margin: 0 10px 0 5px;
            }
            .order-info-item {
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                justify-content: center;
                text-align: center;
            }
        }
    }
}
</style>
